package de.slothsoft.wasbinich.android.database.webservice;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.StatusLine;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpRequestBase;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;

import android.util.Log;
import de.slothsoft.wasbinich.core.database.DatabaseException;
import de.slothsoft.wasbinich.core.database.DatabaseExceptionCode;
import de.slothsoft.wasbinich.core.database.webservice.RestCommunicator;
import de.slothsoft.wasbinich.core.database.webservice.WebserviceUtil;

public class AndroidRestCommunicator implements RestCommunicator {

    private static final String CLIENT_CREDENTIALS = "V2FzIEJpbiBJY2ggQXBwOkQyNDVCQ0U3LUEyNTEtNEI4OC04QUY0LTJGQTA1RDJCNTA0Mw=="; //$NON-NLS-1$

    @Override
    public String get(String url) throws DatabaseException {
	HttpClient client = new DefaultHttpClient();
	return performRequest(client, new HttpGet(url));
    }

    @Override
    public String post(String url, Map<String, String> parameters) throws DatabaseException {
	try {
	    HttpClient client = new DefaultHttpClient();
	    HttpPost httpPost = new HttpPost(url);
	    httpPost.addHeader("Authorization", "Basic " + CLIENT_CREDENTIALS); //$NON-NLS-1$ //$NON-NLS-2$
	    httpPost.setEntity(new UrlEncodedFormEntity(convertToNameValues(parameters)));
	    return performRequest(client, httpPost);
	} catch (UnsupportedEncodingException e) {
	    throw new DatabaseException(DatabaseExceptionCode.INVALID_DATA, e.getMessage(), e);
	}
    }

    protected List<NameValuePair> convertToNameValues(Map<String, String> parameters) {
	List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>();
	for (Entry<String, String> parameterEntry : parameters.entrySet()) {
	    nameValuePairs.add(new BasicNameValuePair(parameterEntry.getKey(), parameterEntry.getValue()));
	}
	return nameValuePairs;
    }

    protected String performRequest(HttpClient client, HttpRequestBase request) throws DatabaseException {
	try {
	    HttpResponse response = client.execute(request);
	    StatusLine statusLine = response.getStatusLine();
	    int statusCode = statusLine.getStatusCode();

	    HttpEntity entity = response.getEntity();
	    String reponseString = getResponseString(entity);

	    if (statusCode != 200)
		throw WebserviceUtil.createDatabaseException(reponseString);
	    return reponseString;
	} catch (DatabaseException e) {
	    throw e;
	} catch (Exception e) {
	    Log.e("slothsoft", "Error while accessing " + request.getURI()); //$NON-NLS-1$ //$NON-NLS-2$
	    Log.e("slothsoft", e.getMessage()); //$NON-NLS-1$
	    throw new DatabaseException(DatabaseExceptionCode.UNKNOWN, e.getMessage(), e);
	}
    }

    protected String getResponseString(HttpEntity entity) throws IllegalStateException, IOException {
	StringBuilder result = new StringBuilder();
	InputStream content = entity.getContent();
	BufferedReader reader = new BufferedReader(new InputStreamReader(content));
	String line;
	while ((line = reader.readLine()) != null) {
	    result.append(line);
	}
	return result.toString();
    }

}
